/**
 *
 */
package com.lehecai.core.lottery.fetcher.lotterydraw.impl.worker;

import com.lehecai.core.lottery.LotteryType;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDraw;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDrawPrizeItem;
import com.lehecai.core.util.CharsetConstant;
import com.lehecai.core.util.CoreFetcherUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.CssSelectorNodeFilter;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.tags.TableRow;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 全国开奖页面爱彩网通用抓取页面实现类
 * @author sushi
 */
public class CountryLotteryDrawFetchWorkerAiCaiPiao extends AbstractLotteryDrawFetchWorker {

    private static final Map<LotteryType, String> lotteryTypeCovertionMap = new HashMap<LotteryType, String>();

    private static final Map<LotteryType, Integer> lotteryTypeNodeMap = new HashMap<LotteryType, Integer>();

    private static final String URL_DEFAULT = "http://kaijiang.aicai.com";

    private static final String URL_HISTORY = "http://kaijiang.aicai.com/open/historyIssue.do";

    protected String siteName = "AiCaiPiao";

    protected String lotteryScope = "全国开奖";

    static {
        lotteryTypeCovertionMap.put(LotteryType.SSQ, "101");
        lotteryTypeCovertionMap.put(LotteryType.DLT, "201");

        //不同彩种对应的解析节点(用于在开奖页面取得当前彩期)
        lotteryTypeNodeMap.put(LotteryType.SSQ, 0);
        lotteryTypeNodeMap.put(LotteryType.DLT, 1);
    }

    public CountryLotteryDrawFetchWorkerAiCaiPiao(LotteryType lotteryType) {
        super(lotteryType);
    }

    @Override
    public LotteryDraw fetchResult(String phase) {
        return this.fetchResultDetail(phase);
    }

    @Override
    public LotteryDraw fetchResultDetail(String phase) {
        LotteryType lotteryType = this.getLotteryType();
        String url = URL_DEFAULT;
        String pageInfo = "列表页面" + url;
        String logHeader = "==" + lotteryScope + "==" + siteName + "==" + pageInfo + "==抓取==" + getLotteryType().getName() + "==";

        String fetchUrl = this.getResultDetailUrl(phase);
        if (StringUtils.isEmpty(fetchUrl)) {
            logger.error("==详细页面==抓取=={}==期号：{}==详细地址不存在，返回null", lotteryType.getName(), phase);
            return null;
        }

        fetchUrl += "?" + System.currentTimeMillis();
        Map<String, String> headerParams = new HashMap<String, String>();
        headerParams.put("Referer", "http://kaijiang.aicai.com/");
        headerParams.put("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36");

        Map<String, String> requestParams = new HashMap<String, String>();

        String lotteryTypeExternal = lotteryTypeCovertionMap.get(lotteryType);
        requestParams.put("gameIndex", lotteryTypeExternal);
        if (StringUtils.isNotEmpty(phase)) {
            requestParams.put("issueNo", phase);
        } else {
            // 自动抓取无彩期，从页面上取最近的历史彩期
            String data = CoreFetcherUtils.URLGet(URL_DEFAULT, null, CharsetConstant.CHARSET_UTF8);
            if (data == null || data.indexOf("404 Not Found") > 0) {
                logger.error(logHeader + "data is null or 404 Not Found");
                return null;
            }
            Parser parser = Parser.createParser(data, CharsetConstant.CHARSET_UTF8);
            NodeFilter cssFilter = new CssSelectorNodeFilter("p[class='lot_qs']");
            try {
                NodeList nodeList = parser.extractAllNodesThatMatch(cssFilter);
                Node node = nodeList.elementAt(lotteryTypeNodeMap.get(lotteryType));
                NodeList children = node.getChildren();
                Node node1 = children.elementAt(4);
                String text = node1.getText();
                if (text != null && text.trim().length() > 0) {
                    phase = text.replaceAll("期", "");
                    requestParams.put("issueNo", phase);
                }
            } catch (ParserException e2) {
                logger.error(logHeader + "数据解析错误==" + e2.getMessage(), e2);
                return null;
            }
        }

        String data = CoreFetcherUtils.URLPostWithHeaderParams(fetchUrl,
                headerParams, requestParams, CharsetConstant.CHARSET_UTF8);
        if (StringUtils.isEmpty(data)) {
            logger.error("data is null or 404 Not Found, url={}", fetchUrl);
            return null;
        }

        String levelInfo = "";
        String openTime = "";
        String openResult = "";
        String prizePool = "";
        String saleValue = "";
        List<LotteryDrawPrizeItem> resultDetail = null;
        LotteryDraw lotteryDraw = null;
        try {
            JSONObject jsonObject = JSONObject.fromObject(data);
            levelInfo = jsonObject.getString("levelInfo");
            openTime = jsonObject.getString("openTime");
            openResult = jsonObject.getString("openResult");
            prizePool = jsonObject.getString("prizePool").replaceAll(",", "");
            saleValue = jsonObject.getString("saleValue").replaceAll(",", "");

            lotteryDraw = new LotteryDraw();
            lotteryDraw.setJackpot(prizePool);
            lotteryDraw.setLotteryType(lotteryType);
            lotteryDraw.setPhase(phase);
            lotteryDraw.setVolumeOfSales(saleValue);
            lotteryDraw.setTimeDraw(getTimeDraw(phase, openTime));
            lotteryDraw.setResult(getOpenResult(openResult));
            resultDetail = this.getResultDetailByTable(levelInfo);
            lotteryDraw.setResultDetail(resultDetail);
        } catch (Exception e) {
            logger.error("转换抓取结果数据出错, data={}", data);
        }
        logger.info(logHeader + "结束==");
        return lotteryDraw;
    }

    private String getTimeDraw(String phase, String openTime) {
        String temp = phase;
        if (!phase.startsWith("20") && phase.length() < 7) {
            temp = "20" + phase;
        }
        String year = temp.substring(0, 4);
        return year + "-" + openTime;
    }

    private String getOpenResult(String openResult) {
        openResult = openResult.replaceAll(" class='blue'", "").replaceAll("<i>", "").replaceAll("</i>", ",");
        StringBuilder sb = new StringBuilder(openResult);
        sb.deleteCharAt(sb.lastIndexOf(","));
        return sb.toString();
    }

    private List<LotteryDrawPrizeItem> getResultDetailByTable(String levelInfo) throws ParserException {
        List<LotteryDrawPrizeItem> list = new ArrayList<LotteryDrawPrizeItem>();
        LotteryDrawPrizeItem lotteryDrawPrizeItem = null;
        Parser parser = new Parser();
        parser.setInputHTML(levelInfo);
        parser.setEncoding(CharsetConstant.CHARSET_UTF8);
        NodeFilter filter = new NodeClassFilter(TableRow.class);
        NodeList nodeList = parser.parse(filter);
        for (int i = 0; i < nodeList.size(); ++i) {
            if (nodeList.elementAt(i) instanceof TableRow) {//tr
                TableRow tag = (TableRow) nodeList.elementAt(i);
                TableColumn[] columns = tag.getColumns();//td
                String prizeLevel = columns[0].toPlainTextString().trim();
                String prize = columns[1].toPlainTextString().trim().replaceAll(",", "").replaceAll("元", "");
                String count = columns[2].toPlainTextString().trim().replaceAll("注", "");
                lotteryDrawPrizeItem = new LotteryDrawPrizeItem();
                lotteryDrawPrizeItem.setName(prizeLevel);
                lotteryDrawPrizeItem.setWinningCount(count);
                lotteryDrawPrizeItem.setPrizeAmount(prize);
                list.add(lotteryDrawPrizeItem);
            }
        }
        return list;
    }

    @Override
    protected String getResultDetailUrl(String phase) {
        LotteryType lotteryType = this.getLotteryType();
        if (!lotteryTypeCovertionMap.containsKey(lotteryType)) {
            return null;
        }
        return URL_HISTORY;
    }

    @Override
    protected String getResultUrl(String phase) {
        return null;
    }
}
